from apscheduler.triggers.cron import CronTrigger
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.jobstores.memory import MemoryJobStore
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
class AutoScheduler(object):
    __instance = None
    def __init__(self):
        self._logger = None
        self.jobstores = {
            'default': MemoryJobStore()
        }
        self.executors = {
            'default': ThreadPoolExecutor(20),
            'processpool': ProcessPoolExecutor(6)
        }
        self.job_defaults = {
            'coalesce': True,
            'max_instances': 10
        }
        self._scheduler = BlockingScheduler(jobstores=self.jobstores, executors=self.executors, job_defaults=self.job_defaults)
    def __new__(cls, *args, **kwd):
        if AutoScheduler.__instance is None:
            AutoScheduler.__instance = object.__new__(cls, *args, **kwd)
        return AutoScheduler.__instance
    def set_scheduler(self,scheduler):
        self._scheduler = scheduler
    def add_job(self,func,args,trigger=None):
        if trigger is None:
            self._scheduler.add_job(func=func,trigger= CronTrigger(second='*/5'),args= args)
        else:
            self.add_job(func=func,trigger=trigger,args=args)
    def add_special_job(self,func,args,trigger=None):
        trigger_sepcial = CronTrigger(hour='0', minute='0', second='0') if trigger is None else trigger
        self._scheduler.add_job(func=func,trigger=trigger_sepcial,args=args)
    def add_alike_jobs(self,func,dict_args,gevent_client=None,db_session=None,refresh_time=None):

        for args in dict_args:
            trigger = CronTrigger(second='*/' + str(refresh_time)) if refresh_time is not None else CronTrigger(
                second='*/5')
            if gevent_client is None:
                if db_session is None:
                    self._scheduler.add_job(func=func, trigger=trigger, args=[dict_args[args]])
                else :
                    self._scheduler.add_job(func=func, trigger=trigger, args=[db_session,dict_args[args]])
            else :
                if db_session is None:
                    self._scheduler.add_job(func=func, trigger=trigger,args=[gevent_client, dict_args[args]])
                else:
                    self._scheduler.add_job(func=func,trigger=trigger,args=[gevent_client,db_session,dict_args[args]])

    def start(self):
        try:
            self._scheduler.start()
        except Exception as err:
            if self._scheduler.running:
                self._scheduler.shutdown()
            raise Exception('任务调度器启动失败！错误信息为：' + str(err))
    def shutdown(self,wait=True):
        if self._scheduler.running:
            self._scheduler.shutdown(wait=wait)
